"""
    python 方法的装饰器

    1、非实例方法修饰器
    2、实例中方法修饰器
    3、类方法修饰器
    4、类的静态方法 @classmethod

"""
import datetime
import time

"""
    1、非类方法装饰器
"""


def decorator_method(func: object) -> object:
    """
        返回一个内部的装饰器方法 wrapper。 wrapper 必须和被装饰方法的参数个数相同。
    :param func:
    :return:
    """

    def wrapper(arg1, arg2):
        """
            装饰器处理方法
        :param arg1:
        :param arg2:
        :return:
        """
        start_time = time.time()
        result = func(arg1, arg2)
        end_time = time.time()
        print(end_time - start_time)
        print("当前时间：", datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
        return result

    # 返回内部的装饰器处理方法
    return wrapper


# 函数装饰器
@decorator_method
def add(a, b):
    return a + b


"""
    2、类方法的装饰器
"""


def decorator_class_method(func):
    """
        声明一个装饰器方法接受实例的形参
    :param func:
    :return:
    """

    def wrapper(instance, arg1, arg2):
        val = time.time()
        result = func(instance, arg1, arg2)
        print(time.time() - val)

        print("now time:", datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
        return result

    return wrapper


# 类方法的装饰器
class Method(object):

    @decorator_class_method
    def add(self, a, b):
        return a + b


"""
    3、装饰器类
       init 函数保存被修饰func函数引用
       call 函数在执行被修饰函数时候，调用该函数
"""


class Decorator(object):

    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print(args)
        result = self.func(args[0], args[1])
        return result


@Decorator
def add2(a, b):
    return a + b


"""
    静态方法
      静态方法必须传cls 类实例，作为首个形参。相当于实例函数self一样
"""


class StaticMethodTest(object):

    @classmethod
    def test(cls, a, b):
        return a + b


if __name__ == '__main__':
    print(add(1, 2))

    print(Method().add(2, 3))

    print(add2(2, 2))

    print(StaticMethodTest.test(4, 2))
